package com.aviator.executor;

import com.aviator.domain.TestAviator;
import com.googlecode.aviator.AviatorEvaluator;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: Jiangxx
 * @Date: 2021/12/30
 * @Description: 变量语法糖、nil对象、日期比较
 */
public class AviatorExecutor09 {

    public static void main(String[] args) {
        /**
         * 变量语法糖：Aviator 有个方便用户使用变量的语法糖, 当你要访问变量a中的某个属性b, 那么你可以通过a.b访问到, 更进一步,
         * a.b.c将访问变量a的b属性中的c属性值, 推广开来也就是说 Aviator 可以将变量声明为嵌套访问的形式。
         * TestAviator类符合JavaBean规范, 并且是 public 的，我们就可以使用语法糖:
         */
        TestAviator foo = new TestAviator(100, 3.14f, new Date());
        Map<String, Object> env = new HashMap<String, Object>();
        env.put("foo", foo);
        System.out.println(AviatorEvaluator.execute("'foo.i = '+foo.i", env));   // foo.i = 100
        System.out.println(AviatorEvaluator.execute("'foo.f = '+foo.f", env));   // foo.f = 3.14
        System.out.println(AviatorEvaluator.execute("'foo.date.year = '+(foo.date.year+1990)", env));  // foo.date.year = 2106

        /* 对于深度嵌套并且同时有数组的变量访问，例如 foo.bars[1].name，从 3.1.0 版本开始， aviator 通过引用变量来支持（quote variable)： */
        /**
         * 引用变量要求以 # 符号开始，并且变量名中不能包含其他变量，也就是并不支持 #foo.bars[i].name 这样的访问，
         * 如果有此类特殊需求，请通过自定义函数实现。
         *
         * 对于一些深度嵌套的 List 或者数组的访问， commons-beanutils还支持类似 #map.array.[0].name这样的访问语法，
         * 如果不满足JavaBean规范的，请尝试使用这样的语法做嵌套访问。
         */
        System.out.println(AviatorEvaluator.execute("'hello,' + #foo.bars[1].name", env));

        /**
         * nil对象：nil是 Aviator 内置的常量,类似 java 中的null,表示空的值。nil跟null不同的在于,
         * 在 java 中null只能使用在==、!=的比较运算符,而nil还可以使用>、>=、<、<=等比较运算符。
         * Aviator 规定,任何对象都比nil大除了nil本身。用户传入的变量如果为null,将自动以nil替代。
         */

        /* nil与String相加的时候,跟 java 一样显示为 null */
        AviatorEvaluator.execute("nil == nil");   //true
        AviatorEvaluator.execute(" 3> nil");      //true
        AviatorEvaluator.execute(" true!= nil");  //true
        AviatorEvaluator.execute(" ' '>nil ");    //true
        AviatorEvaluator.execute(" a==nil ");     //true, a 是 null


        /**
         * 日期比较：Aviator 并不支持日期类型,如果要比较日期,你需要将日期写字符串的形式,
         * 并且要求是形如 “yyyy-MM-dd HH:mm:ss:SS”的字符串,否则都将报错。
         * 字符串跟java.util.Date比较的时候将自动转换为Date对象进行比较:
         */

        /* String除了能跟String比较之外,还能跟nil和java.util.Date对象比较。 */
        Map<String, Object> env1 = new HashMap<String, Object>();
        final Date date = new Date();
        String dateStr = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SS").format(date);
        env.put("date", date);
        env.put("dateStr", dateStr);
        Boolean result = (Boolean) AviatorEvaluator.execute("date==dateStr", env1);
        System.out.println(result);  // true
        result = (Boolean) AviatorEvaluator.execute("date > '2010-12-20 00:00:00:00' ", env1);
        System.out.println(result);  // true
        result = (Boolean) AviatorEvaluator.execute("date < '2200-12-20 00:00:00:00' ", env1);
        System.out.println(result);  // true
        result = (Boolean) AviatorEvaluator.execute("date==date ", env1);
        System.out.println(result);  // true

    }
}
